﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace BuddHa.Common.RegexOpex
{
    public class ConstRegex
    {
        public const string 数字 = "^[0-9]*$";
        public const string n位的数字 = "^\\d{0}$";
        public const string 至少n位的数字 = "^\\d{0,}$";
        public const string m到n位的数字 = "^\\d{m,0}$";
        public const string 零和非零开头的数字 = "^(0|[1-9][0-9]*)$";
        public const string 有两位小数的正实数 = "^[0-9]+(.[0-9]{2})?$";
        public const string 有1到3位小数的正实数 = "^[0-9]+(.[0-9]{1,3})?$";
        public const string 非零的正整数 = "^\\+?[1-9][0-9]*$";
        public const string 非零的负整数 = "^\\-[1-9][]0-9]*$";
        public const string 长度为3的字符 = "^.{3}$";
        public const string 字母组成字符串 = "^[A-Za-z]+$";
        public const string 大写字母组成字符串 = "^[A-Z]+$";
        public const string 小写字母组成字符串 = "^[a-z]+$";
        public const string 数字和英文字母组成的字符串 = "^[A-Za-z0-9]+$";
        public const string 数字和英文字母下划线组成的字符串 = "^\\w+$";
        // 验证用户密码 长度6到18位，只能包含字符、数字和下划线
        public const string 六到十八位字符数字和下划线 = "^[a-zA-Z]\\w{5,17}$";
        // 验证是否含有^%&’,;=?$\"
        public const string 验证特殊符号 = "[^%&’,;=?$\x22]+";
        public const string 汉字 = "^[\u4e00-\u9fa5]{0,}$";
        public const string 验证Emile地址 = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
        public const string 验证InternetURL = "^http://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?$";
        // "XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"
        public const string 验证电话号码 = "^(\\(\\d{3,4}-)|\\d{3.4}-)?\\d{7,8}$";
        // 15到18位数字
        public const string 验证身份证号 = "^\\d{17}(?:\\d|X)$";
        public const string 验证一年的12个月 = "^(0?[1-9]|1[0-2])$";
        public const string 验证一个月的31天 = "^((0?[1-9])|((1|2)[0-9])|30|31)$";
        public const string 匹配空行 = "\\n[\\s| ]*\\r";
        public const string 匹配HTML标记 = "/<(.*)>.*<\\/\\1>|<(.*) \\/>/";
        public const string 匹配首尾空格 = "(^\\s*)|(\\s*$)";

        /// <summary>
        /// 计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int CalDoubleByte(string str)
        {
            Regex regex = new Regex("[^\x00-\xff]");
            var outputStr = regex.Replace(str, "aa");
            return outputStr.Length;
        }

        /// <summary>
        /// 去除首尾空格
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string TrimStartAndEnd(string str)
        {
            Regex regex = new Regex(匹配首尾空格);
            var outputStr = regex.Replace(str, "");
            return outputStr;
        }

        /// <summary>
        /// 判断是否合法的IP4地址
        /// </summary>
        public static bool MatchIP4(string ip4)
        {
            string ipPattern = "^((25[0-4]|2[0-4]|1\\d{2}|[1-9]?\\d)\\.){3}(25[0-4]|2[0-4]|1\\d{2}|[1-9]?\\d)$";
            Regex regex = new Regex(ipPattern);
            return regex.IsMatch(ip4);
        }

        /// <summary>
        /// 判断是否合法的IP6地址
        /// </summary>
        public static bool MatchIP6(string ip6)
        {
            string ipPattern = "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$";
            Regex regex = new Regex(ipPattern);
            return regex.IsMatch(ip6);
        }

        /// <summary>
        /// 可判断格式如下
        /// YYYY | YYYY-MM | YYYY-MM-DD | YYYY-MM-DD HH:MM:SS | YYYY-MM-DD HH:MM:SS.FFF
        /// </summary>
        public static bool IsDate(string str)
        {
            try
            {
                DateTime.Parse(str);
                return true;
            }
            catch 
            {
                return false;
            }
        }

        /// <summary>
        /// 判断一个字符串是否为合法整数(不限制长度)
        /// </summary>
        public static bool IsInteger(string str)
        {
            string pattern = @"^\d*$";
            return Regex.IsMatch(str, pattern);
        }

        /// <summary>
        /// 判断一个字符串是否为合法数字(0-32整数)
        /// </summary>
        public static bool IsNumber(string str)
        {
            return IsNumber(str, 32, 0);
        }

        /// <summary>
        /// 判断一个字符串是否为合法数字(指定整数位数和小数位数)
        /// </summary>
        public static bool IsNumber(string str, int precision, int scale)
        {
            if ((precision == 0) && (scale == 0))
            {
                return false;
            }
            string pattern = @"(^\d{1," + precision + "}";
            if (scale > 0)
            {
                pattern += @"\.\d{0," + scale + "}$)|" + pattern;
            }
            pattern += "$)";
            return Regex.IsMatch(str, pattern);
        }

        /// <summary>
        /// 验证身份证号
        /// </summary>
        public static bool IsIdentityCard(string str)
        { 
            Regex regex = new Regex(验证身份证号);
            return regex.IsMatch(str);
        }
    }
}
